package com.lorenzogao.pley.ui.widget

import android.Manifest
import android.content.Context
import android.util.Log
import com.jakewharton.rxbinding2.view.RxView
import com.lorenzogao.pley.R
import com.lorenzogao.pley.bean.AppDownloadInfo
import com.lorenzogao.pley.bean.AppInfo
import com.lorenzogao.pley.bean.BaseBean
import com.lorenzogao.pley.common.Constant
import com.lorenzogao.pley.common.rx.RxHttpReponseCompat
import com.lorenzogao.pley.common.util.ACache
import com.lorenzogao.pley.common.util.AppUtils
import com.lorenzogao.pley.common.util.AppUtils.runApp
import com.lorenzogao.pley.common.util.PermissionUtil
import io.reactivex.Observable
import io.reactivex.ObservableSource
import io.reactivex.functions.Consumer
import io.reactivex.functions.Function
import retrofit2.http.GET
import retrofit2.http.Path
import zlc.season.rxdownload2.RxDownload
import zlc.season.rxdownload2.entity.DownloadEvent
import zlc.season.rxdownload2.entity.DownloadFlag
import java.io.File

/**
 * 作者：Lorenzo Gao
 * Date: 2018/1/12
 * Time: 9:06
 * 邮箱：2508719070@qq.com
 * Description:
 */
class DownloadButtonConntroller(rxDownload: RxDownload) {


    private var mRxDownload: RxDownload = rxDownload

    private var mApi: Api

    init {
        mApi = mRxDownload.retrofit.create(Api::class.java)

    }


    fun handClick(btn: DownloadProgressButton, appInfo: AppInfo) {

        if (mApi == null) {
            return
        }



        isAppInstalled(btn.context, appInfo)
                .flatMap(Function<DownloadEvent, ObservableSource<DownloadEvent>> { t: DownloadEvent ->
                    if (DownloadFlag.UN_INSTALL == t.flag) {
                        return@Function isAppFileExsit(btn.context, appInfo)
                    }
                    return@Function Observable.just(t)

                }).flatMap(Function<DownloadEvent, ObservableSource<DownloadEvent>> {

            t: DownloadEvent ->
            if (DownloadFlag.FILE_EXIST == t.flag) {
                return@Function getAppDownloadInfo(appInfo).flatMap(Function<AppDownloadInfo, ObservableSource<DownloadEvent>> { t: AppDownloadInfo ->
                    appInfo.appDownloadInfo = t
                    return@Function receiveDownloadStatus(t)

                })
            }
            return@Function Observable.just(t)
        }).subscribe(DownloadConsumer(btn, appInfo))


    }

    private fun bindClick(btn: DownloadProgressButton, appInfo: AppInfo) {

        RxView.clicks(btn).subscribe(Consumer {

            var flag = btn.getTag(R.id.tag_apk_flag)

            Log.e("flag------->", flag.toString())

            when (flag) {

                DownloadFlag.INSTALLED -> runApp(btn.context, appInfo.packageName)
                DownloadFlag.STARTED -> pauseDownload(appInfo)
                DownloadFlag.PAUSED -> startDownload(btn, appInfo)
                DownloadFlag.NORMAL -> startDownload(btn, appInfo)
                DownloadFlag.COMPLETED -> installApp(btn.context, appInfo)

            }

        })

    }

    private fun installApp(context: Context, appInfo: AppInfo) {

        var path = ACache.get(context).getAsString(Constant.APK_DOWNLOAD_DIE) + File.separator + appInfo.releaseKeyHash

        AppUtils.installApk(context, path)
    }

    private fun startDownload(btn: DownloadProgressButton, appInfo: AppInfo) {

        PermissionUtil.requestPermission(btn.context, Manifest.permission.WRITE_EXTERNAL_STORAGE).subscribe({ aBoolean: Boolean ->
            if (aBoolean) {
                if (appInfo.appDownloadInfo == null) {
                    getAppDownloadInfo(appInfo).subscribe({
                        appDownloadinfo ->
                        appInfo.appDownloadInfo = appDownloadinfo

                        download(btn, appInfo)

                    })

                } else {
                    download(btn, appInfo)
                }
            } else {

            }


        })


    }

    private fun download(btn: DownloadProgressButton, info: AppInfo) {
        mRxDownload.serviceDownload(info.appDownloadInfo.downloadUrl, info.releaseKeyHash).subscribe()

        mRxDownload.receiveDownloadStatus(info.appDownloadInfo.downloadUrl).subscribe(DownloadConsumer(btn, info))

    }

    private fun pauseDownload(appInfo: AppInfo) {
        mRxDownload.pauseServiceDownload(appInfo.appDownloadInfo.downloadUrl).subscribe()
    }

    private fun isAppInstalled(context: Context, appInfo: AppInfo): Observable<DownloadEvent> {

        var downevent = DownloadEvent()

        downevent.flag = if (AppUtils.isInstalled(context, appInfo.packageName)) DownloadFlag.INSTALLED else DownloadFlag.UN_INSTALL

        return Observable.just(downevent)

    }

    private fun isAppFileExsit(context: Context, appInfo: AppInfo): Observable<DownloadEvent> {

        var path = ACache.get(context).getAsString(Constant.APK_DOWNLOAD_DIE) + File.separator + appInfo.releaseKeyHash


        var file = File(path)


        var downevent = DownloadEvent()

        downevent.flag = if (file.exists()) DownloadFlag.FILE_EXIST else DownloadFlag.NORMAL


        return Observable.just(downevent)


    }

    private fun getDownloadStatus(appDownloadInfo: AppDownloadInfo): Observable<DownloadEvent> {


        return mRxDownload.receiveDownloadStatus(appDownloadInfo.downloadUrl)

    }


    private fun getAppDownloadInfo(appInfo: AppInfo): Observable<AppDownloadInfo> {
        return mApi.getAppDownloadInfo(appInfo.id).compose(RxHttpReponseCompat.compatResult())
    }


    private fun receiveDownloadStatus(appDownloadInfo: AppDownloadInfo): Observable<DownloadEvent> {

        return mRxDownload.receiveDownloadStatus(appDownloadInfo.downloadUrl)
    }


    inner class DownloadConsumer(b: DownloadProgressButton, appInfo: AppInfo) : Consumer<DownloadEvent> {

        private var btn: DownloadProgressButton = b
        private var mAppInfo: AppInfo = appInfo

        override fun accept(t: DownloadEvent) {
            val flag = t.flag

            btn.setTag(R.id.tag_apk_flag, flag)

            bindClick(btn, mAppInfo)

            when (flag) {
                DownloadFlag.INSTALLED -> btn.setText("运行")
                DownloadFlag.STARTED -> {
                    btn.setProgress(t.downloadStatus.percentNumber.toInt())
                }

                DownloadFlag.PAUSED ->{
                    btn.setProgress(t.downloadStatus.percentNumber.toInt())
                    btn.paused()
                }
                DownloadFlag.COMPLETED -> btn.setText("安装")
                DownloadFlag.NORMAL -> btn.download()
                DownloadFlag.FAILED -> btn.setText("失败")



            }

        }
    }

    interface Api {
        @GET("download/{id}")
        fun getAppDownloadInfo(@Path("id") id: Int): Observable<BaseBean<AppDownloadInfo>>
    }

}


